package com.lechi.web.server.handle;

import com.alibaba.fastjson2.JSON;
import com.lechi.web.common.utils.bean.BeanUtils;
import com.lechi.web.constants.Constants;
import com.lechi.web.framework.util.GuavaCacheUtil;
import com.lechi.web.framework.websocket.WebSocketServer;
import com.lechi.web.framework.websocket.WebSocketUtil;
import com.lechi.web.system.domain.IotMonitorDataBo;
import com.lechi.web.system.domain.IotWeatherSensorParseBo;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 北斗报文接收
 */
@Slf4j
@Sharable
public final class BeiDouInboundMessageHandler extends SimpleChannelInboundHandler<ByteBuf> implements BaseWeatherInboundHandle {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) {
        String hostName = getHostName(ctx);
        String dataRecord = byteBuf.toString(Charset.defaultCharset());
        log.error("BEIDOU-RSMC 设备地址： {} ，开始解析报文：{}", hostName, dataRecord);
        String[] sensorData = dataRecord.split(",");
        if (!dataRecord.startsWith("$") || sensorData.length < 3) {
            getKeysByValue(hostName).forEach(deviceId -> WebSocketServer.sendInfo(deviceId + 1000, JSON.toJSONString(Map.of("response", dataRecord))));
            return;
        }
        String deviceStation = sensorData[0].substring(1);
        Date watchTime = Optional.ofNullable(sensorData[1]).map(this::parseStrToDate).orElse(null);
        Map<Integer, String> sensorMap = "A".equals(sensorData[2]) ? GuavaCacheUtil.getSH_A_Map() : GuavaCacheUtil.getSH_B_Map();
        Map<String, IotWeatherSensorParseBo> sensorParseBoMap = GuavaCacheUtil.getWeatherParseTableMap().getOrDefault(deviceStation, new HashMap<>());
        List<IotMonitorDataBo> beidouDeviceDataList = new ArrayList<>();
        for (int i = 3, length = sensorData.length; i < length; i++) {
            if ("/".equals((sensorData[i]))) continue;
            String sensorSign = sensorMap.get(i - 3);
            if (sensorParseBoMap.containsKey(sensorSign)) {
                IotWeatherSensorParseBo sensorParseBo = sensorParseBoMap.get(sensorSign);
                GuavaCacheUtil.getDeviceLastDated().put(sensorParseBo.getDeviceId().toString(), new Date());
                GuavaCacheUtil.getDeviceIdAndIPMap().put(sensorParseBo.getDeviceId(), hostName);
                IotMonitorDataBo iotMonitorPageData = new IotMonitorDataBo();
                BeanUtils.copyProperties(sensorParseBo, iotMonitorPageData);
                String doubleValue = Optional.ofNullable(sensorData[i]).orElse("");
                try {
                    var v = Double.parseDouble(doubleValue) * Optional.ofNullable(sensorParseBo.getIntFactor()).orElse(1d);
                    String formatV = new DecimalFormat(Optional.ofNullable(sensorParseBo.getSensorDigit()).filter(n -> n > 0).map(n -> "0." + "0".repeat(n)).orElse("0")).format(v);
                    iotMonitorPageData.setValue(Float.parseFloat(formatV)).setStringValue(formatV).setDoubleValue(formatV).setDateTime(watchTime);
                } catch (NumberFormatException e) {
                    log.error("BEIDOU-RSMC 解析报文NumberFormatException异常：{}", dataRecord);
                    continue;
                }
                beidouDeviceDataList.add(iotMonitorPageData);
                insertData(iotMonitorPageData);
                alarmRuleChain(iotMonitorPageData);
                WebSocketUtil.sendToMonitorPage(iotMonitorPageData);
                GuavaCacheUtil.getMonitorDataMap().put(iotMonitorPageData.getDeviceId(), iotMonitorPageData.getSensorAliasId(), iotMonitorPageData);
            }
        }
        WebSocketUtil.sendToDevicePage(Constants.BEIDOU_RSMC, beidouDeviceDataList, dataRecord);
    }
}
